﻿using Mg.ExpressionParser.DbSqlParser;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace Mg.ExpressionParser
{
    public class SqlPack
    {
        private static readonly List<string> _listEnglishWords = new List<string> { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", };

        private Dictionary<string, string> _dicTableName = new Dictionary<string, string>();
        private Queue<string> _queueEnglishWords = new Queue<string>(_listEnglishWords);

        private readonly IDbSqlParser _sqlParser;

        public bool IsSingleTable { get; set; }

        public List<string> SelectFields { get; set; }

        public StringBuilder Sql { get; private set; }

        public Dictionary<string, object> DbParams { get; private set; }

        public List<IDbDataParameter> SqlParameters { get; set; }

        public SqlPack(IDbSqlParser parser)
        {
            DbParams = new Dictionary<string, object>();
            Sql = new StringBuilder();
            SelectFields = new List<string>();
            _sqlParser = parser;
            SqlParameters = new List<IDbDataParameter>();
        }

        public string SelectFieldStr
        {
            get
            {
                return string.Join(",", SelectFields);
            }
        }

        public int Length
        {
            get
            {
                return Sql.Length;
            }
        }

        public char this[int index]
        {
            get
            {
                return Sql[index];
            }
        }



        public void Clear()
        {
            SelectFields.Clear();
            Sql.Clear();
            DbParams.Clear();
            _dicTableName.Clear();
            _queueEnglishWords = new Queue<string>(_listEnglishWords);
            SqlParameters.Clear();
        }

        public void AddDbParameter(object parameterValue)
        {
            if (parameterValue == null || parameterValue == DBNull.Value)
                Sql.Append(" NULL");
            else
            {
                string name = _sqlParser.DbParamPrefix + "param" + DbParams.Count;
                DbParams.Add(name, parameterValue);
                SqlParameters.Add(_sqlParser.GetDataParameter(name, parameterValue));
                Sql.Append(" " + name);
            }
        }

        public bool SetTableAlias(string tableName)
        {
            if (!_dicTableName.Keys.Contains(tableName))
            {
                _dicTableName.Add(tableName, _queueEnglishWords.Dequeue());
                return true;
            }
            return false;
        }

        public string GetTableAlias(string tableName)
        {
            if (!IsSingleTable && _dicTableName.Keys.Contains(tableName))
            {
                return _dicTableName[tableName];
            }
            return "";
        }

        public override string ToString()
        {
            return Sql.ToString();
        }

        public static SqlPack operator +(SqlPack sqlPack, string sql)
        {
            sqlPack.Sql.Append(sql);
            return sqlPack;
        }
    }
}
